package com.dempsey.user.controller;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dempsey.api.model.LoginUser;
import com.dempsey.common.core.domain.AjaxResult;
import com.dempsey.common.core.domain.R;
import com.dempsey.common.security.annotation.RequiresRoles;
import com.dempsey.common.security.service.TokenService;
import com.dempsey.common.security.utils.SecurityUtils;
import com.dempsey.user.dao.Address;
import com.dempsey.user.dao.User;
import com.dempsey.user.dao.UserRole;
import com.dempsey.user.service.AddressService;
import com.dempsey.user.service.RoleService;
import com.dempsey.user.service.UserRoleService;
import com.dempsey.user.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * The type User controller.
 *
 * @author Dempsey  Date 2022/5/1 Description
 */
@RestController
@RequestMapping("/user")
public class UserController {

    private final static Log log = LogFactory.get();

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private AddressService addressService;


    @GetMapping("/a")
    public AjaxResult a() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        return AjaxResult.success(loginUser);
    }

    @RequiresRoles("普通用户")
    @GetMapping("/b")
    public AjaxResult b() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        return AjaxResult.success(loginUser);
    }


    /**
     * 通过用户名获取用户
     * 用于登录（校验密码逻辑放在服务端）等场景
     *
     * @param username the username
     * @return the user by username
     */
    @PostMapping("/getUserByUsername")
    public R<User> getUserByUsername(@RequestParam("username") String username) {
        log.info("请求参数: {}", username);
        User user = userService.getUserByUsername(username);
        return R.ok(user);
    }


    /**
     * Gets user role by user id.
     *
     * @param userId the user id
     * @return the user role by user id
     */
    @PostMapping("/getUserRoleByUserId")
    public R<String> getUserRoleByUserId(@RequestParam("userId") int userId) {
        log.info("请求参数: {}", userId);
        String roleName = roleService.getRoleByUserId(userId);

        return R.ok(roleName);
    }

    @PostMapping("/createUser")
    public R<User> createUser(@RequestBody User user) {
        log.info("创建新用户：{}", user);
        User newUser = userService.createUser(user);
        // 添加角色信息，新用户必为普通用户
        UserRole userRole = new UserRole(1, user.getUserId());
        userRoleService.save(userRole);
        return R.ok(newUser);
    }

    /**
     * 更新用户信息
     * 用于：
     * 更新登录用户的最后登录时间
     * 更新用户信息修改
     *
     * @return the ajax result
     */
    @PostMapping("/updateUserInfo")
    public AjaxResult updateUserInfo(@RequestBody User user) {
        log.info("请求参数: {}", user);
        userService.updateUser(user);
        return AjaxResult.success();
    }

    private com.dempsey.api.domain.User convertModuleUser2ApiUser(User user) {
        com.dempsey.api.domain.User apiUser = new com.dempsey.api.domain.User();
        BeanUtils.copyProperties(user, apiUser);
        return apiUser;
    }

    @PostMapping("/updateUserRole")
    public AjaxResult updateUserRole(@RequestParam int roleId) {
        log.info("请求参数: {}", roleId);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Integer userId = loginUser.getUser().getUserId();

        QueryWrapper<UserRole> qw = new QueryWrapper<>();
        qw.eq("user_id", userId);
        userRoleService.update(new UserRole(roleId, userId), qw);

        return AjaxResult.success();
    }

    @PostMapping("/getUserSelfInfo")
    public AjaxResult getUserSelfInfo() {
        AjaxResult ajax = AjaxResult.success();

        LoginUser loginUser = SecurityUtils.getLoginUser();
        User user = userService.getById(loginUser.getUser().getUserId());
        ajax.put("user", user);
        ajax.put("userRole", loginUser.getRole());

        return ajax;
    }

    @PostMapping("/getUserById")
    public AjaxResult getUserById(@RequestParam int userId) {
        log.info("请求参数: {}", userId);
        User user = userService.getById(userId);
        return AjaxResult.success(user);
    }

    @PostMapping("/createAddress")
    public AjaxResult createAddress(@RequestBody Address address) {
        log.info("请求参数: {}", address);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        address.setUserId(loginUser.getUser().getUserId());
        addressService.save(address);
        return AjaxResult.success();
    }

    /**
     * Disable address.
     * 用户可以逻辑删除地址，
     * 但是旧订单还要查到地址，所以不能完全删
     *
     * @param addressId the address id
     * @return the ajax result
     */
    @PostMapping("/disableAddress")
    public AjaxResult disableAddress(@RequestParam int addressId) {
        log.info("请求参数: {}", addressId);
        addressService.updateById(Address.builder().addressId(addressId).status(1).build());
        return AjaxResult.success();
    }

    @PostMapping("/updateAddress")
    public AjaxResult updateAddress(@RequestBody Address address) {
        log.info("请求参数: {}", address);
        addressService.updateById(address);
        return AjaxResult.success();
    }

    /**
     * Gets addresses.
     * 只有用户自己才需要获取地址列表
     *
     * @return the addresses
     */
    @PostMapping("/getAddresses")
    public AjaxResult getAddresses() {
        LoginUser loginUser = SecurityUtils.getLoginUser();

        // 用户能看到的地址，是没有被自己弃用的地址
        QueryWrapper<Address> qw = new QueryWrapper<>();
        qw.eq("user_id", loginUser.getUser().getUserId())
                .eq("status", 0);
        List<Address> addressList = addressService.list(qw);

        return AjaxResult.success(addressList);
    }

    /**
     * Gets address.
     *
     * @param addressId the address id
     * @return the address
     */
    @PostMapping("/getAddressById")
    public AjaxResult getAddressById(@RequestParam int addressId) {
        Address address = addressService.getById(addressId);
        return AjaxResult.success(address);
    }

}
